Implementing OWNERDRAWN Edit Controls in MFC/Multipad ----------------------------------------------------- The Magma Edit DLL/VBX comes with replacement drop-in classes for MFC. The CMagmaEdit and CMagmaEditView classes can be used instead of the CEdit and CEditView classes which comes as part of MFC. Many users of the Magma Edit DLL like to take advantage of the ownerdrawn style which the edit control supports. Using the ownerdrawn style, the application is given the first crack at drawing a line of text. Ownerdrawn lines are good for things like syntax highlighting, custom coloring, etc. This technote summarizes experiences with getting the MFC Multipad sample to work with an ownerdrawn MagmaEdit control. We need a way to create a CMagmaEditView control with the ES_OWNERDRAW style in it. Since the Magma Editor DLL sends the ME_DRAWITEM message to the parent of the edit control, we need to derive a new parent window class whose main job is to process the ownerdraw messages. In this example, the new class processes only the ME_DRAWITEM and ME_MEASUREITEM messages --- you can expand it so that it processes the ME_DELETEITEM message too. In MULTIPAD.H, we added the following two classes : class COwnerDrawEditView : public CMagmaEditView { DECLARE_DYNCREATE(COwnerDrawEditView) protected: virtual BOOL PreCreateWindow(CREATESTRUCT& cs); }; class CMDIOwnerDrawChildWnd : public CMDIChildWnd { DECLARE_DYNCREATE(CMDIOwnerDrawChildWnd) //{{AFX_MSG(CMDIOwnerDrawChildWnd) afx_msg long OnMEDrawItem(UINT nIDCtl, long lpMIS); afx_msg long OnMEMeasureItem(UINT nIDCtl, long lpMIS); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; The main purpose of COwnerDrawEditView is to force the ES_OWNERDRAW style to be passed to the Magma Editor DLL when we create an edit control. Therefore, COwnerDrawEditView merely 'front-ends' the PreCreateWindow function. CMDIOwnerDrawChildWnd contains the code to process the various ownerdrawn messages, such as ME_DRAWITEM, ME_MEASUREITEM, and ME_DELETEITEM. In DOCVIEW.CPP, we added #ifdef USE_MAGMA IMPLEMENT_DYNCREATE(COwnerDrawEditView, CMagmaEditView) BOOL COwnerDrawEditView::PreCreateWindow(CREATESTRUCT& cs) { cs.style |= ES_OWNERDRAW | ES_HASSTRINGS; return CMagmaEditView::PreCreateWindow(cs); } IMPLEMENT_DYNCREATE(CMDIOwnerDrawChildWnd, CMDIChildWnd) BEGIN_MESSAGE_MAP(CMDIOwnerDrawChildWnd, CMDIChildWnd) //{{AFX_MSG_MAP(CMDIOwnerDrawChildWnd) ON_MESSAGE(ME_DRAWITEM, OnMEDrawItem) ON_MESSAGE(ME_MEASUREITEM, OnMEMeasureItem) //}}AFX_MSG_MAP END_MESSAGE_MAP() long CMDIOwnerDrawChildWnd::OnMEDrawItem(UINT nIDCtl, long lpMIS) { LPMEDRAWITEMSTRUCT lpMID = (LPMEDRAWITEMSTRUCT) lpMIS; // Highlight C++ comments which start at column 1 if (lpMID->lpText[0] == '/' && lpMID->lpText[1] == '/') { COLORREF rgbOld = ::SetTextColor(lpMID->hDC, RGB(0, 128, 0)); ::TextOut(lpMID->hDC, lpMID->rcItem.left, lpMID->rcItem.top, lpMID->lpText, lstrlen(lpMID->lpText)); ::SetTextColor(lpMID->hDC, rgbOld); return TRUE; } else { return FALSE; } } long CMDIOwnerDrawChildWnd::OnMEMeasureItem(UINT nIDCtl, long lpMIS) { LPMEASUREITEMSTRUCT lpMID = (LPMEASUREITEMSTRUCT) lpMIS; return FALSE; // let the edit control use the height } #endif In Multipad, we need to create a document template using the new classes we derived. In MULTIPAD.CPP, we used the following call to AddDocTemplate : AddDocTemplate(new CMultiDocTemplate(IDR_TEXTTYPE, RUNTIME_CLASS(CPadDoc), RUNTIME_CLASS(CMDIOwnerDrawChildWnd), RUNTIME_CLASS(COwnerDrawEditView))); The processing of the ME_DRAWITEM message is very simplistic. You can choose to implement more complicated processing. The source code to the MEWIN sample program (available with the Magma Edit DLL) contains some code to do syntax highlighting for C programs. For more info on the Magma Edit DLL : Demos : GO MAGMA on Compuserve ftp.uu.net, directory /vendor/uno Compuserve mail : 75300,2062 Internet : 75300.2062@compuserve.com magma@bix.com Magma Systems also sells the MEWEL User Interface Library, an implementatiom of the Windows API, MFC and OWL for Dos text, DOs graphics, UNIX Text, and MOTIF.